package com.example.avplayer;

import android.media.MediaCodec;
import android.media.MediaFormat;
import android.util.Log;
import android.view.Surface;

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.ByteBuffer;

public class H264Player implements Runnable{
    private final  String TAG = "H264Player";

    private String path;

    private Surface surface;
    MediaCodec mediaCodec;
    public H264Player(String path, Surface surface) {
        this.path = path;
        this.surface = surface;
        try {
            mediaCodec = MediaCodec.createDecoderByType("video/avc");
            MediaFormat videoFormat = MediaFormat.createVideoFormat(MediaFormat.MIMETYPE_VIDEO_AVC, 480, 720);
            videoFormat.setInteger(MediaFormat.KEY_FRAME_RATE,15);
            mediaCodec.configure(videoFormat,surface,null,0);
            // 解码
        } catch (IOException e) {
            e.printStackTrace();
            Log.e(TAG,"不支持硬解码");
        }
    }

    public void paly() {
        mediaCodec.start();
        new Thread(this).start();
    }

    @Override
    public void run() {
        decodeH264();
    }

    private void decodeH264() {

        // 读取文件的数据 byte

        byte[] fileBytes = getFileBytes(path);


        int startIndex = 0;// 帧开始位置
        MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
        for (;;) {
            //找到帧，
            int nextFrame = findNextFrame(startIndex+2, fileBytes);

            // 寻找可用的 buffer //
            //        // 把 帧丢入到 empty buffer

            int inIndex = mediaCodec.dequeueInputBuffer(10000);
            if (inIndex>=0) {
                ByteBuffer outputBuffer = mediaCodec.getInputBuffer(inIndex);
                int len = nextFrame -startIndex;
                Log.e("输入大小",len+"");
                outputBuffer.put(fileBytes,startIndex,len);

                mediaCodec.queueInputBuffer(inIndex,0,len,0,0);
            }
            startIndex = nextFrame;
            int outIndex =mediaCodec.dequeueOutputBuffer(info,10000);
            if (outIndex >= 0) {
                try {
                    Thread.sleep(33);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                mediaCodec.releaseOutputBuffer(outIndex, true);
            }
        }

        //


    }

    private int findNextFrame(int startIndex, byte[] fileBytes) {

        for (int i = startIndex; i < fileBytes.length; i++) {
            if ((fileBytes[i]==0x00 && fileBytes[i+1] == 0x00 && fileBytes[i+2]==0x00 && fileBytes[i+3]==0x01)
            || ((fileBytes[i] == 0x00) && (fileBytes[i + 1] == 0x00) && (fileBytes[i + 2] == 0x01))) {
                return i;
            }
        }
        return  -1;

    }

    private byte[] getFileBytes(String path) {
        FileInputStream fileInputStream;
        try {
             fileInputStream = new FileInputStream(path);
            byte buff[] = new byte[1024];
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            int len;
            while ((len = fileInputStream.read(buff,0,1024))!=-1) {
                    byteArrayOutputStream.write(buff,0,len);
            }
            buff = byteArrayOutputStream.toByteArray();
            return  buff;

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

return null;
    }
}
